﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;


namespace ConsoleApplication1
{
    public abstract class Robot
    {
        static int id = 1;
        int[] coordenadas;
        string tipo;
        bool outUp;

        public bool OutUp
        {
            get { return outUp; }
            set { outUp = value; }
        }
        bool outDown;

        public bool OutDown
        {
            get { return outDown; }
            set { outDown = value; }
        }
        bool outLeft;

        public bool OutLeft
        {
            get { return outLeft; }
            set { outLeft = value; }
        }
        bool outRight;

        public bool OutRight
        {
            get { return outRight; }
            set { outRight = value; }
        }
        bool outFront;

        public bool OutFront
        {
            get { return outFront; }
            set { outFront = value; }
        }
        bool outBack;

        public bool OutBack
        {
            get { return outBack; }
            set { outBack = value; }
        }
        //Color colorRobot;
        string salida;
        public Robot()
        {
            this.OutBack = true;
            this.OutDown = true;
            this.OutLeft = true;
            this.OutRight = true;
            this.OutFront = true;
            this.OutBack = true;

        }

        public string Salida
        {
            get { return salida; }
            set { salida = value; }
        }

        public virtual void Pintar(Laberinto lab, List<Bitmap> imagenesTodas)
        {
            Celda celdaAtual = lab.Terreno[this.Coordenadas[0], this.Coordenadas[1], this.Coordenadas[2]];
            int[] colorActual = new int[]{imagenesTodas[this.Coordenadas[2]].GetPixel(this.Coordenadas[0], this.Coordenadas[1]).R,
                imagenesTodas[this.Coordenadas[2]].GetPixel(this.Coordenadas[0], this.Coordenadas[1]).G,
                imagenesTodas[this.Coordenadas[2]].GetPixel(this.Coordenadas[0], this.Coordenadas[1]).B};
            celdaAtual.ColoresRespuesta.Add(colorActual);
            if (Salida == "U")
            {

                while (celdaAtual != lab.GoalUp && celdaAtual != null)
                {
                    celdaAtual = celdaAtual.PredecesorUp;
                    celdaAtual.SumColores[0] += colorActual[0];
                    celdaAtual.SumColores[1] += colorActual[1];
                    celdaAtual.SumColores[2] += colorActual[2];
                    celdaAtual.NumColores++;
                    //celdaAtual.ColoresRespuesta.Add(colorActual);
                }
            }
            else if (Salida == "D")
            {

                while (celdaAtual != lab.GoalDown && celdaAtual != null)
                {
                    celdaAtual = celdaAtual.PredecesorDown;
                    celdaAtual.SumColores[0] += colorActual[0];
                    celdaAtual.SumColores[1] += colorActual[1];
                    celdaAtual.SumColores[2] += colorActual[2];
                    celdaAtual.NumColores++;
                    //celdaAtual.ColoresRespuesta.Add(colorActual);
                }
            }
            else if (Salida == "L")
            {

                while (celdaAtual != lab.GoalLeft && celdaAtual!= null)
                {
                    celdaAtual = celdaAtual.PredecesorLeft;
                    celdaAtual.SumColores[0] += colorActual[0];
                    celdaAtual.SumColores[1] += colorActual[1];
                    celdaAtual.SumColores[2] += colorActual[2];
                    celdaAtual.NumColores++;
                    //celdaAtual.ColoresRespuesta.Add(colorActual);
                }
            }
            else if (Salida == "R")
            {

                while (celdaAtual != lab.GoalRight && celdaAtual != null)
                {
                    celdaAtual = celdaAtual.PredecesorRight;
                    celdaAtual.SumColores[0] += colorActual[0];
                    celdaAtual.SumColores[1] += colorActual[1];
                    celdaAtual.SumColores[2] += colorActual[2];
                    celdaAtual.NumColores++;
                    //celdaAtual.ColoresRespuesta.Add(colorActual);
                }
            }
            else if (Salida == "F")
            {

                while (celdaAtual != lab.GoalFront && celdaAtual != null)
                {
                    celdaAtual = celdaAtual.PredecesorFront;
                    celdaAtual.SumColores[0] += colorActual[0];
                    celdaAtual.SumColores[1] += colorActual[1];
                    celdaAtual.SumColores[2] += colorActual[2];
                    celdaAtual.NumColores++;
                    //celdaAtual.ColoresRespuesta.Add(colorActual);
                }
            }
            else if (Salida == "B")
            {

                while (celdaAtual != lab.GoalBack && celdaAtual != null)
                {
                    celdaAtual = celdaAtual.PredecesorBack;
                    celdaAtual.SumColores[0] += colorActual[0];
                    celdaAtual.SumColores[1] += colorActual[1];
                    celdaAtual.SumColores[2] += colorActual[2];
                    celdaAtual.NumColores++;
                    //celdaAtual.ColoresRespuesta.Add(colorActual);
                }
            }
        }

        public virtual void ElegirRuta(Laberinto lab)
        {//Abajo Izquierda Frente Derecha Atras Arriba (D L F R B U)
            //setear salida
            
            int costoMin = lab.Terreno[this.Coordenadas[0],this.Coordenadas[1],this.Coordenadas[2]].CostoDown;//Si es 2D el goalDown será null, pero 
            // al no ejecutarse el algoritmo Pathfind, los valores de costoDown para cada celda serán int.MaxValue por el constructor de celda.
            // Debido a lo anterior, para el caso 2D esto siempre será reemplazado, pues si el laberinto tiene solución deberá encontrar valores para los demás costos menores a int.MaxValue
            this.Salida = "D"; 
            int costoAux = lab.Terreno[this.Coordenadas[0], this.Coordenadas[1], this.Coordenadas[2]].CostoLeft;
            if (costoMin >= costoAux) // >= para que en caso de igualdad, prefiera Left debido al orden de preferencias
            {
                costoMin = lab.Terreno[this.Coordenadas[0], this.Coordenadas[1], this.Coordenadas[2]].CostoLeft;
                this.Salida = "L";
            }
            costoAux = lab.Terreno[this.Coordenadas[0], this.Coordenadas[1], this.Coordenadas[2]].CostoFront;
            if (costoMin >= costoAux) // >= para que en caso de igualdad, prefiera Front debido al orden de preferencias
            {
                costoMin = lab.Terreno[this.Coordenadas[0], this.Coordenadas[1], this.Coordenadas[2]].CostoFront;
                this.Salida = "F";
            }
            costoAux = lab.Terreno[this.Coordenadas[0], this.Coordenadas[1], this.Coordenadas[2]].CostoRight;
            if (costoMin >= costoAux)
            {
                costoMin = lab.Terreno[this.Coordenadas[0], this.Coordenadas[1], this.Coordenadas[2]].CostoRight;
                this.Salida = "R";
            }
            costoAux = lab.Terreno[this.Coordenadas[0], this.Coordenadas[1], this.Coordenadas[2]].CostoBack;
            if (costoMin >= costoAux)
            {
                costoMin = lab.Terreno[this.Coordenadas[0], this.Coordenadas[1], this.Coordenadas[2]].CostoBack;
                this.Salida = "B";
            }
            costoAux = lab.Terreno[this.Coordenadas[0], this.Coordenadas[1], this.Coordenadas[2]].CostoUp;
            if (costoMin >= costoAux)
            {
                costoMin = lab.Terreno[this.Coordenadas[0], this.Coordenadas[1], this.Coordenadas[2]].CostoUp;
                this.Salida = "U";
            }
        }
       
        #region Getters y Setters
        public static int Id
        {
            get { return Robot.id; }
            set { Robot.id = value; }
        }
        

        public int[] Coordenadas
        {
            get { return coordenadas; }
            set { coordenadas = value; }
        }
        

        public string Tipo
        {
            get { return tipo; }
            set { tipo = value; }
        }
        

        //public Color ColorRobot
        //{
        //    get { return colorRobot; }
        //    set { colorRobot = value; }
        //}
        #endregion


    }
}
